package com.blyat.xsoft.gateway.restful.controller;

import com.blyat.xsoft.gateway.restful.entity.User;
import com.blyat.xsoft.gateway.restful.service.AuthorityService;
import com.blyat.xsoft.kernel.restful.view.ResultModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/**
 * @Auther: syh
 * @Date: 2020/8/24
 * @Description:
 */
@RestController
@RequestMapping("gateway")
public class GatewayController {

    @RequestMapping("welcome")
    public Mono<Object> welcome() {
        return Mono.just("welcome to use Blayt-XSoft-Gateway.");
    }

    @RequestMapping("current/user")
    public Mono<ResultModel> user() {
        return ReactiveSecurityContextHolder.getContext()
                .switchIfEmpty(Mono.error(new IllegalStateException("ReactiveSecurityContext is empty")))
                .map(SecurityContext::getAuthentication)
                .map(Authentication::getPrincipal)
                .cast(User.class)
                .map(u -> ResultModel.SUCCESS(u));
    }

    @Autowired
    private AuthorityService authorityService;

    @RequestMapping("current/authority")
    public Mono<ResultModel> authority() {

        return ReactiveSecurityContextHolder.getContext()
                .switchIfEmpty(Mono.error(new IllegalStateException("ReactiveSecurityContext is empty")))
                .map(SecurityContext::getAuthentication)
                .map(Authentication::getPrincipal)
                .cast(User.class)
                .flatMapMany(user -> authorityService.getAuthorityTree(user.getId()))
                .collectList()
                .map(list -> ResultModel.SUCCESS(list));
    }

    @RequestMapping("current/logout")
    public Mono<ResultModel> logout() {
        return Mono.just(ResultModel.SUCCESS("注销成功"));
    }
}
